﻿using System.Collections.Concurrent;
using System.Threading;

namespace StarUtils.Cache
{
    public class CacheStatsInfo
    {
        private readonly ConcurrentDictionary<string, CacheStatsCounter> _counters;

        private const string DefaultKey = "cache_stats";

        public CacheStatsInfo()
        {
            _counters = new ConcurrentDictionary<string, CacheStatsCounter>();
        }

        public void OnHit()
        {
            GetCounter().Increment(StatsType.Hit);
        }

        public void OnMiss()
        {
            GetCounter().Increment(StatsType.Missed);
        }

        public long GetStatistic(StatsType statsType)
        {
            return GetCounter().Get(statsType);
        }

        private CacheStatsCounter GetCounter()
        {
            if (!_counters.TryGetValue(DefaultKey, out var value))
            {
                value = new CacheStatsCounter();
                if (_counters.TryAdd(DefaultKey, value))
                {
                    return value;
                }

                return GetCounter();
            }

            return value;
        }
    }
    public class CacheStatsCounter
    {
        private readonly long[] _counters = new long[2];

        public void Increment(StatsType statsType)
        {
            Interlocked.Increment(ref _counters[(int)statsType]);
        }

        public long Get(StatsType statsType)
        {
            return Interlocked.Read(ref _counters[(int)statsType]);
        }
    }
}
